#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>

#include <input_manager.h>

//定义头指针
static PInputDevice g_InputDevs =NULL;


//定义锁（为了上锁）
static pthread_mutex_t g_tMutex  = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t  g_tConVar = PTHREAD_COND_INITIALIZER;

/*开始 实现环形缓冲区*/
#define BUFFER_LEN 20
static int g_iRead 	= 0;
static int g_iWrite = 0;
static InputEvent g_atInputEvents[BUFFER_LEN];
static int isInputBufferFull(void)
{
	//如果下一个位置等于读的位置的话则表示是满的
	return(g_iRead==((g_iWrite+1)%BUFFER_LEN));
}


static int isInputBufferEmpty(void)
{
	//如果读写位置相等的话则表示是空的
	return(g_iRead==g_iWrite) ;

}


//存放数据
static void PutInputEventToBuffer(PInputEvent ptInputEvent)
{
	if(!isInputBufferFull())//如果环形buffer没有存满的话
	{
		g_atInputEvents[g_iWrite]= *ptInputEvent;
		g_iWrite=(g_iWrite+1)%BUFFER_LEN;
		
	}


}

//获得数据
static int GetInputEventFromBuffer(PInputEvent ptInputEvent)
{
	if(!isInputBufferEmpty())//如果环形buffer没有存满的话
	{
		*ptInputEvent=g_atInputEvents[g_iRead] ;
		g_iRead=(g_iRead+1)%BUFFER_LEN;
		return 1;
	}
	else{
	return 0;
	}

}


/*结束 实现环形缓冲区*/



//注册函数
void RegisterInputDevice(PInputDevice ptInputDev)
{
	ptInputDev->ptNext = g_InputDevs;
	g_InputDevs = ptInputDev;
}
//这里的注册也就是把不同的设备插入g_InputDevs链表中
void InputInit(void)
{
	/*注册触摸屏设备*/
	extern void TouchscreenRegiser(void);
	TouchscreenRegiser();
	/*注册网络输入设备*/
	extern void NetinputRegiser(void);
	NetinputRegiser();

}

//线程启动后需要做的事情
static void *input_recv_thread_func (void *data)
{
	PInputDevice ptInputDev = (PInputDevice)data;
	InputEvent tEvent;
	int ret;

	while (1)
	{
		/* 读数据 */
		ret = ptInputDev->GetInputEvent(&tEvent);

		if (!ret)
		{	
			/* 保存数据 */
			pthread_mutex_lock(&g_tMutex);//上锁
			PutInputEventToBuffer(&tEvent);//保存数据到tEvent

			/* 唤醒等待数据的线程 */
			pthread_cond_signal(&g_tConVar); /* 通知接收线程 */
			pthread_mutex_unlock(&g_tMutex);//释放锁
		}
	}

	return NULL;
}



void IntpuDeviceInit(void)
{
	//对于每个设备都初始化它，并且创建对应的线程
	int ret;
	pthread_t tid;
	PInputDevice ptTmp = g_InputDevs;
	while(ptTmp)
	{
		//初始化设备
		ret=ptTmp->DeviceInit(); 

		//创建线程
		if(!ret)
		{
			ret = pthread_create(&tid, NULL, input_recv_thread_func, ptTmp);
		
		}
		ptTmp=ptTmp->ptNext;
	}
}

//获得数据
int GetInputEvent(PInputEvent ptInputEvent)
{
	InputEvent tEvent;
	int ret;
	/* 无数据则休眠 */
	pthread_mutex_lock(&g_tMutex);
	if (GetInputEventFromBuffer(&tEvent))
	{
		*ptInputEvent = tEvent;
		pthread_mutex_unlock(&g_tMutex);
		return 0;
	}
	else
	{
		/* 休眠等待 */
		pthread_cond_wait(&g_tConVar, &g_tMutex);	
		if (GetInputEventFromBuffer(&tEvent))
		{
			*ptInputEvent = tEvent;
			ret = 0;
		}
		else
		{
			ret = -1;
		}
		pthread_mutex_unlock(&g_tMutex);		
	}
	return ret;

}



